<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>文档对象模型使用(Document Object Model use)</title>
  <!-- 
  DOM（Document Object Model）是浏览器为网页提供的一个接口，它将网页的结构表示为对象，使得JavaScript可以动态地访问和更新网页的内容、结构和样式。
  1. DOM 的基本概念
  - 节点（Node）：在 DOM 的上下文中，节点是节点树中的单个点。文档本身、元素、文本以及注释都是节点。
  - 文档（Document）：文档对象模型（DOM）是一个网络文档的编程接口。它代表页面，以便程序可以改变文档的结构、风格和内容。DOM 将文档表示为节点和对象；这样，编程语言就可以与页面交互。整个网页的根节点，表示整个 HTML 文档。
  - 元素（Element）：元素是网页的一部分。在 XML 和 HTML 中，一个元素可以包含一个数据项，或是一块文本，或是一张照片，亦或是什么也不包含。一个典型的元素包括一个具有一些属性的开始标签，中间的文本内容和一个结束标签。网页中的各种标签，如 <div>、<p> 等。每个元素都是一个节点。

  2. 访问 DOM 元素
  - 通过 ID 访问：
    let elementById = document.getElementById('elementId');
  - 通过类名访问：
    let elementsByClassName = document.getElementsByClassName('className');
  - 通过标签名访问：
    let elementsByTagName = document.getElementsByTagName('div');
  - 使用选择器访问：
    let elementBySelector = document.querySelector('.className'); // 选择第一个匹配的元素
    let elementsBySelectorAll = document.querySelectorAll('div'); // 选择所有匹配的元素

  3. 创建和插入元素
  - 创建新元素：
    let newElement = document.createElement('div'); // 创建一个新的 div 元素
  - 插入元素：
    document.body.appendChild(newElement); // 将新元素添加到文档的 body 中
  - 在特定位置插入元素：
    let referenceElement = document.getElementById('referenceId');
    referenceElement.parentNode.insertBefore(newElement, referenceElement); // 在指定元素之前插入

  4. 修改元素内容和属性
  - 修改文本内容：
    let element = document.getElementById('elementId');
    element.textContent = '新的文本内容'; // 修改元素的文本内容
  - 修改 HTML 内容：
    element.innerHTML = '<span>新的 HTML 内容</span>'; // 修改元素的 HTML 内容
  - 修改属性：
    element.setAttribute('class', 'newClass'); // 设置元素的类名
    let className = element.getAttribute('class'); // 获取元素的类名

  5. 删除元素
  - 删除元素：
    let elementToRemove = document.getElementById('elementId');
    elementToRemove.parentNode.removeChild(elementToRemove); // 从文档中删除元素

  6. 样式操作
  - 修改元素样式：
    element.style.color = 'red'; // 修改元素的文本颜色
    element.style.display = 'none'; // 隐藏元素
  - 添加和移除类：
    element.classList.add('newClass'); // 添加类
    element.classList.remove('oldClass'); // 移除类

  7. 事件处理
  - 添加事件监听器：
    element.addEventListener('click', function() {
      alert('元素被点击了！');
    });
  - 移除事件监听器：
    function handleClick() {
      alert('元素被点击了！');
    }
    element.addEventListener('click', handleClick);
    element.removeEventListener('click', handleClick); // 移除事件监听器

  总结
  - DOM 的基本概念：DOM 是网页的结构化表示，允许 JavaScript 动态操作网页内容。
  - 访问元素：可以通过 ID、类名、标签名和选择器访问 DOM 元素。
  - 创建和插入元素：可以创建新元素并将其插入到 DOM 中。
  - 修改内容和属性：可以修改元素的文本、HTML 内容和属性。
  - 删除元素：可以从 DOM 中删除不再需要的元素。
  - 样式操作：可以通过 JavaScript 修改元素的样式和类。
  - 事件处理：可以为元素添加和移除事件监听器，以响应用户的操作。

   -->
</head>
<body>

  <!-- 文档注释(document comments) -->
  普通文本(plain text)

  <div class="document-object-model">
    <h3>文档对模型</h3>
    <p>document object model</p>
  </div>

  <ul>
    <li>document</li>
    <li>object</li>
    <li>model</li>
  </ul>

  <input type="text">
  <button>按钮</button>

  <script>
    // 1. 元素属性
    // 1.1 HTMLElement
    HTMLElement
    // 1.2 Element
    Element
    // 1.3 Node
    Node
    // 1.4 Document
    Document
    // 1.5 Window
    Window
    // 1.6 Event
    Event
    // 1.7. EventTarget
    EventTarget
    // 1.8 HTMLLIElement
    HTMLLIElement
    // 1.9 HTMLInputElement
    HTMLInputElement
    // 1.10 HTMLButtonElement
    HTMLButtonElement

    // 2. DOM 操作
    // 2.1 访问元素
    const domEl = document.body.children[0]
    console.log("访问元素", domEl);
    domEl.innerHTML = "DOM 操作"
    domEl.style.color = "red"

    domEl.style.fontSize = "30px"
    domEl.nextElementSibling.style.color = "blue"
    
    // 2.2 节点之间的导航
    const htmlEl = document.documentElement // <html>
    const bodyEl = document.body  // <body>
    const headEl = document.head  // <head>
    const titleEl = document.title  // <title>
    const metaEl = document.querySelector("meta")  // <meta>
    const linkEl = document.querySelector("link")  // <link>
    console.log("节点之间的导航", htmlEl, bodyEl, headEl, titleEl, metaEl, linkEl);

    // 2.3 节点关系
    const domBodyEl = document.body // <body>
    const domBodyElFirstChild = domBodyEl.firstChild // <div>
    // 获取注释
    const domBodyElFirstChildComment = domBodyElFirstChild.nextSibling // <!-- 注释 -->
    // 获取父节点
    const domBodyElFirstChildParentNode = domBodyElFirstChildComment.parentNode // <body>
    console.log("节点关系", domBodyElFirstChildComment, domBodyElFirstChildParentNode);

    // 2.4 节点操作
    const divEl = document.createElement("div")
    divEl.innerHTML = "我是新创建的 div 元素"
    divEl.style.color = "green"
    divEl.style.fontSize = "30px"
    // 将新创建的 div 元素添加到 body 子元素最后位置中
    document.body.appendChild(divEl)
    
    // 2.5 节点属性
    const divEl2 = document.createElement("div")
    divEl2.innerHTML = "我是新创建的 div 元素"
    divEl2.style.color = "green"
    divEl2.style.fontSize = "30px"
    // 将新创建的 div 元素添加到 body 子元素最后位置中
    document.body.appendChild(divEl2)
    // 修改属性
    divEl2.setAttribute("data-id", "100")
    divEl2.setAttribute("class", "box")
    // 获取属性
    console.log("节点属性", divEl2.getAttribute("data-id"), divEl2.getAttribute("class"));

    // 2.6 节点删除
    // 删除 divEl2
    document.body.removeChild(divEl2)
    // 删除 divEl
    divEl.remove()

    // 2.7 节点克隆
    const divEl3 = document.createElement("div")
    divEl3.innerHTML = "我是新创建的 div 元素"
    divEl3.style.color = "green"
    divEl3.style.fontSize = "30px"
    // 将新创建的 div 元素添加到 body 子元素最后位置中
    document.body.appendChild(divEl3)
    // 克隆 divEl3
    const divEl4 = divEl3.cloneNode(true)
    document.body.appendChild(divEl4)

    // 3. 元素之间的导航
    const childEl = bodyEl.children // 获取 body 子元素
    const firstChildEl = bodyEl.firstElementChild // 获取 body 子元素
    const lastChildEl = bodyEl.lastElementChild // 获取 body 子元素
    const nextSiblingEl = bodyEl.nextElementSibling // 获取 body 下一个兄弟元素
    const previousSiblingEl = bodyEl.previousElementSibling // 获取 body 上一个兄弟元素
    const parentEl = bodyEl.parentElement // 获取 body 父元素
    const childrenEl = bodyEl.children[0] // 获取 body 子元素
    console.log("body 子元素", childEl, firstChildEl, lastChildEl, nextSiblingEl, previousSiblingEl, parentEl, childrenEl);
    

  </script>
  
</body>
</html>